#include "qipan.h"
#include<QPainter>
#include <QDebug>
#include <QMessageBox>

QiPan::QiPan(QWidget *parent)
    : QWidget{parent},
    m_currentRole(PLAYER),
    m_gameOver(true),
    m_hoverRow(-1),
    m_hoverCol(-1),
    m_hoverFlag(false)



{
    // 创建开始按钮
    m_startButton = new QPushButton("重新开始", this);
    m_startButton->setGeometry(10, m_boardSize * m_cellSize +10, 100, 30); // 位置在棋盘下方
    connect(m_startButton, &QPushButton::clicked, this, &QiPan::startNewGame);
    m_undoButton = new QPushButton("悔棋", this);
    m_undoButton->setGeometry(120, m_boardSize * m_cellSize + 10, 80, 30);
    connect(m_undoButton, &QPushButton::clicked, this, &QiPan::undoMove);

    // 设置窗口大小（确保按钮可见）
    setFixedSize(m_boardSize * m_cellSize + 2 * m_margin,
                 m_boardSize * m_cellSize + 50);
    // 初始化棋盘状态
    resetBoard();




    setMouseTracking(true);  //设置鼠标追踪


    setFixedSize(m_boardSize * m_cellSize + 2 * m_margin,
                 m_boardSize * m_cellSize + 2 * m_margin + 80); // 底部留空间放按钮

}


void QiPan::paintEvent(QPaintEvent *event) //绘画事件
{
    QPainter painter(this);  //创建画家类

    painter.setRenderHint(QPainter::Antialiasing);  //去除毛刺，抗锯齿

    QColor background = QColor(210, 180, 140);  //淡灰色
    painter.fillRect(rect(),background);

    for(int idx = 0;idx < m_boardSize;idx++)  //绘制棋盘
    {
        painter.drawLine(m_margin+idx*m_cellSize,m_margin,
                         m_margin+idx*m_cellSize,m_margin+(m_boardSize-1)*m_cellSize) ;  //绘制竖线

        painter.drawLine(m_margin, m_margin + idx * m_cellSize,
                         m_margin + (m_boardSize - 1)*m_cellSize,m_margin + idx * m_cellSize); //绘制横线
    }
    /*绘制悬停点坐标*/
    if(m_hoverFlag ==true &&(m_hoverRow >=0&& m_hoverRow <m_boardSize)&&(m_hoverCol >=0 && m_hoverCol <m_boardSize)&&m_board[m_hoverRow][m_hoverCol] ==EMPTY)
    {
        painter.setBrush(Qt::red);  //设置笔刷
        painter.drawEllipse(QPoint(m_margin + m_hoverRow*m_cellSize,m_margin + m_hoverCol * m_cellSize),
                            m_cellSize / 6,m_cellSize/6);
    }

    for(int row=0;row<m_boardSize;row++)     //绘制棋子
    {
        for(int col=0;col<m_boardSize;col++)
        {
            if(m_board[row][col]==PLAYER)//玩家1
            {
                painter.setBrush(Qt::black);
                painter.drawEllipse(QPoint(m_margin+row*m_cellSize,m_margin+col*m_cellSize),
                                    m_cellSize/3,m_cellSize/3);
            }
            else if(m_board[row][col]==COMPUTER)//玩家2
            {
                painter.setBrush(Qt::white);
                painter.drawEllipse(QPoint(m_margin+row*m_cellSize,m_margin+col*m_cellSize),
                                    m_cellSize/3,m_cellSize/3);
            }
        }
    }
    QPainter Painter(this);
    painter.setPen(Qt::white);
    QString text = (m_currentRole == PLAYER) ? "当前回合: 黑棋" : "当前回合: 白棋";
    painter.drawText(10, 15, text);
}








void QiPan::mouseMoveEvent(QMouseEvent *event) //鼠标移动事件
{
    int row = (event->x()- m_margin+(m_cellSize /2))/m_cellSize;
    int col = (event->y() - m_margin+(m_cellSize/2))/m_cellSize;


    if((row >=0&&row <m_boardSize)&&(col >=0&&col< m_boardSize))
    {
        if(m_hoverRow !=row|| m_hoverCol !=col)
        {
            m_hoverRow = row;
            m_hoverCol = col;
            m_hoverFlag = true;   //手动触发绘画事件
            update();
        }
    }
    else
    {
        m_hoverFlag = false;

        m_hoverRow = m_hoverCol = -1;  //鼠标不在棋盘，清空悬停点坐标


        update();
    }
}
void QiPan::mousePressEvent(QMouseEvent *event)    //鼠标点击事件
{    if(m_gameOver) return;
    int row = (event->x()- m_margin+(m_cellSize /2))/m_cellSize;
    int col = (event->y() - m_margin+(m_cellSize/2))/m_cellSize;

    /*判断鼠标点击是否在棋盘内部*/
    if((row>=0&&row<m_boardSize)&&(col>=0&&col<m_boardSize)&&m_board[row][col]==EMPTY)
    {
        m_board[row][col] = m_currentRole;  //根据当前回合落子
        m_moveHistory.push(QPoint(row, col));  // 记录落子位置
        update();
        bool res =isCheckWin(row,col,m_currentRole);
        if(res==true)
        {   QString winner = (m_currentRole == PLAYER) ? "黑棋" : "白棋";
            QMessageBox::information(this, "游戏结束", winner + "获胜!");
            m_gameOver = true;
        } else {
            // 切换回合
            m_currentRole = (m_currentRole == PLAYER) ? COMPUTER : PLAYER;
        }
    }
}

bool QiPan::isCheckWin(int row,int col,ROLE role)
{
     int dierctions[4][2] =
    {
        {1,0},
        {0 ,1},
        {1,-1},
        {1,1},
        };            //四个方向

    for(int direct = 0;direct<4;direct++)   //遍历每一个方向
    {
        int cnt=1;
        for(int idx=1;idx<5;idx++)             //向一个方向探测
        {
            int nextRow=row+dierctions[direct][0]*idx;
            int nextCol=col+dierctions[direct][1]*idx;     //下一个点的坐标

            if((nextRow>=0&&nextRow<m_boardSize)&&(nextCol>=0&&nextCol<m_boardSize)&&m_board[nextRow][nextCol]==role)
            {
                cnt++;
            }
            else
            {
                break;

            }
        }
        for(int idx=1;idx<5;idx++)             //向相反方向探测
        {
            int nextRow=row-dierctions[direct][0]*idx;
            int nextCol=col-dierctions[direct][1]*idx;     //下一个点的坐标

            if((nextRow>=0&&nextRow<m_boardSize)&&(nextCol>=0&&nextCol<m_boardSize)&&m_board[nextRow][nextCol]==role)
            {
                cnt++;
            }
            else
            {
                break;

            }
        }

        if(cnt>=5)
        {
            return true;
        }

    }

}


// 清空棋盘数据
void QiPan::resetBoard() {
    for (int i = 0; i < m_boardSize; ++i) {
        for (int j = 0; j < m_boardSize; ++j) {
            m_board[i][j] = EMPTY;
        }
    }
    m_gameOver = false;
    m_currentRole = PLAYER; // 重置为黑棋先手
    update(); // 触发界面重绘
}
void QiPan::startNewGame() {
    m_moveHistory.clear();
    resetBoard(); // 清空棋盘并重置游戏状态
}

void QiPan::undoMove() {
    if (m_moveHistory.isEmpty() || m_gameOver) {
        return;  // 无历史记录或游戏结束时禁止悔棋
    }

    // 撤销最后一步
    QPoint lastMove = m_moveHistory.pop();
    m_board[lastMove.x()][lastMove.y()] = EMPTY;

    // 切换回上一个玩家
    m_currentRole = (m_currentRole == PLAYER) ? COMPUTER : PLAYER;

    update();  // 重绘界面
}





